package com.xxx.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxx.common.Code;
import com.xxx.common.Result;
import com.xxx.dto.UserDto;
import com.xxx.pojo.LoginUser;
import com.xxx.pojo.Role;
import com.xxx.pojo.User;
import com.xxx.pojo.UserRole;
import com.xxx.service.RoleService;
import com.xxx.service.UserRoleService;
import com.xxx.service.UserService;
import com.xxx.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;

    @Transactional
    @PostMapping("/login")
    public Result userLogin(@RequestBody User user){
        return userService.login(user);
    }
    @Transactional
    @GetMapping("/logout")
    public Result userLoginOut(){
        return userService.loginOut();
    }

    @Transactional
    @PostMapping("/add")
    @PreAuthorize("hasAnyAuthority('sys:add:user')")
    public Result userAdd(@RequestBody UserDto userDto){
        if (Objects.isNull(userDto)){
            return Result.error(Code.USER_ERROR,"用户为空,添加失败!~");
        }
        List<Role> roles = userDto.getRoles();
        User user = new User();
        BeanUtils.copyProperties(userDto,user);
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setCreateUser(loginUser.getUser().getName());
        user.setUpdateUser(loginUser.getUser().getName());
        //获取系统当前时间
        LocalDate now = LocalDate.now();

        user.setCreateTime(now);
        user.setUpdateTime(now);
        String password = new BCryptPasswordEncoder().encode(user.getPassword());
        user.setPassword(password);
        boolean save = userService.save(user);
        if (roles != null && roles.size()>0){
            for (Role role : roles) {
                UserRole userRole = new UserRole(user.getUserId(), role.getRoleId(), null, null);
                boolean b = userRoleService.save(userRole);
            }
        }
        if (save){
            return Result.success("添加成功!~");
        }
        return Result.error(Code.USER_ERROR,"添加失败!~");
    }
    @PreAuthorize("hasAnyAuthority('sys:select:user')")
    @Transactional
    @PostMapping("/select")
    public Result selectUserByCondition(@RequestBody User user1,@RequestParam("current") Integer current,@RequestParam("size") Integer size){
        if (Objects.isNull(user1)){
            throw new RuntimeException("数据传输格式错误!~");
        }
        if (user1.getStatus() == null || user1.getStatus().getI() == 2){
            user1.setStatus(null);
        }
        IPage iPage = new Page(current,size);
        IPage page = userService.page(iPage,new LambdaQueryWrapper<User>().eq(user1.getStatus() != null,User::getStatus,user1.getStatus())
                .eq(user1.getUserId() != null && user1.getUserId()>0,User::getUserId,user1.getUserId()).eq(user1.getPhone() != null && user1.getPhone() != "",User::getPhone,user1.getPhone())
                .eq(User::getDelete,0));
        List<User> user = page.getRecords();

        List<UserDto> list = user.stream().map(o -> {
            List<UserRole> userRoleList = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, o.getUserId()).eq(UserRole::getStatus,0));
            List<Role> role = new ArrayList<>();
            if (userRoleList != null){
                for (UserRole userRole : userRoleList) {
                    Role one = roleService.getOne(new LambdaQueryWrapper<Role>().eq(userRole.getRoleId() != null && userRole.getRoleId() > 0, Role::getRoleId, userRole.getRoleId()));
                    role.add(one);
                }
            }
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(o, userDto);
            userDto.setRoles(role);
            return userDto;
        }).collect(Collectors.toList());
        HashMap<String, Object> map = new HashMap<>();
        map.put("list",list);
        map.put("total", page.getTotal());
        return Result.success("",map);
    }

    @Transactional
    @PutMapping("/update")
    @PreAuthorize("hasAnyAuthority('sys:update:user')")
    public Result userUpdate(@RequestBody UserDto userDto){
        if (Objects.isNull(userDto)){
            throw new RuntimeException("数据传输格式错误!~");
        }
        List<Role> roles = userDto.getRoles();
        User user = new User();
        BeanUtils.copyProperties(userDto,user);
        if (user.getPassword() != null && user.getPassword() != ""){
            String password = new BCryptPasswordEncoder().encode(user.getPassword());
            user.setPassword(password);
        }
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setUpdateUser(loginUser.getUser().getName());
        user.setUpdateTime(LocalDate.now());
        if (roles.size()>0){
            boolean update = userRoleService.update(new LambdaUpdateWrapper<UserRole>().set(UserRole::getStatus, 1).
                    eq( user.getUserId() != null,UserRole::getUserId, user.getUserId()));
            for (Role role : roles) {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getUserId());
                userRole.setRoleId(role.getRoleId());
                userRoleService.save(userRole);

            }
        }else {
            boolean update = userRoleService.update(new LambdaUpdateWrapper<UserRole>().set(UserRole::getStatus, 1).
                    eq( user.getUserId() != null,UserRole::getUserId, user.getUserId()));
        }

        boolean b = userService.updateById(user);
        if (!b){
            return Result.error("修改失败!");
        }
        return Result.success("修改成功!");
    }

    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAnyAuthority('sys:delete:user')")
    public Result deleteUserByIds(@RequestBody List<String> userIds){
        boolean b = false;
        if (!Objects.isNull(userIds)){
            for (String userIdString : userIds) {
                Long userId = Long.parseLong(userIdString);
                b = userService.removeById(userId);
                boolean b1 = userRoleService.remove(new LambdaQueryWrapper<UserRole>().eq(userId != null && userId > 0,UserRole::getUserId,userId));
            }
        }
        if (!b){
            return Result.error("删除失败!");
        }
        return Result.success("删除成功!");
    }

    @GetMapping("/token")
    public Result AuthenticationToken(HttpServletRequest request){
        String token = request.getHeader("token");
        try {
            JwtUtil.parseJWT(token);
        } catch (Exception e) {
            return Result.error(50001,"token过期");
        }
        return Result.success("");
    }


    @GetMapping("/get-user")
    public Result getUser(String name){
        List<User> list = userService.list(new LambdaQueryWrapper<User>()
                .like(User::getName, name));

        return list == null? Result.error("无相关数据"): Result.success("success",list);
    }

    @GetMapping("/name")
    public Result getName(){
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String name = loginUser.getUser().getName();
        return Result.success("查询成功",name);
    }

    /**查询当前用户信息**/
    @PostMapping("one_user")
    public Result selectOneUser(@RequestBody User user){
        User one = userService.getOne(new LambdaQueryWrapper<User>().eq(user.getLoginName() != null && user.getLoginName() != "", User::getLoginName, user.getLoginName()));
        return one != null ? Result.success("查询成功",one) : Result.error("密码错误");
    }


    /**修改当前用户信息**/
    @PostMapping("update_user")
    public Result updateOneUser(@RequestBody User user){
        boolean b = userService.updateById(user);
        return b ? Result.success("修改成功") : Result.error("修改失败") ;
    }
}
